﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MessageBox = System.Windows.Forms.MessageBox;

namespace WCFMINERP.ComControls
{
	using System.Collections;
	using DevExpress.XtraEditors;
	using DevExpress.XtraEditors.Controls;
	using DevExpress.XtraEditors.Popup;


	public partial class CheckedComboBoxEditEx : PopupContainerEdit {
		public CheckedComboBoxEditEx() {
			InitializeComponent();
			Init();
		}
		private void InitFilteComboxEdit() {
			//			filteComboxEdit.Dock = DockStyle.Top;
			filteComboxEdit.Visible = true;
			filteComboxEdit.VisblePopup = false;
			filteComboxEdit.LostFocusSelectFirst = false;
			filteComboxEdit.ComboxItemsChanged += ComboxItemsChanged;
		}
		private void Init() {
			fProperties = Properties;
			gridView.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.None;
			gridView.OptionsSelection.EnableAppearanceFocusedCell = false;
			Properties.PopupControl = popupContainerControl;
			this.Properties.ShowPopupCloseButton = false;
			gridView.OptionsBehavior.Editable = false;
			controlAdapter = new GridControlAdapter(gridControl);
			controlAdapter.ShowCheckColumn(gridView);
			controlAdapter.colSelected.BestFit();
			controlAdapter.SelectionCollectionChanged += controlAdapter_SelectionCollectionChanged;
			gridView.CustomRowFilter += gridView_CustomRowFilter;
			gridView.FocusedRowChanged += gridView_FocusedRowChanged;
			this.ButtonClick += CheckedComboBoxEditEx_ButtonClick;
			popupContainerControl.FireScrollEventOnMouseWheel = false;
			popupContainerControl.PopupContainerProperties.AllowMouseWheel = false;
			popupContainerControl.MouseWheel += popupContainerControl_MouseWheel;
			InitFilteComboxEdit();
		}
		private void popupContainerControl_MouseWheel(object sender, MouseEventArgs e) {
		}
		protected override void DoShowPopup() {
			base.DoShowPopup();
			this.PopupForm.Width = this.Width;
		}
		private void CheckedComboBoxEditEx_ButtonClick(object sender, ButtonPressedEventArgs e) {
			this.CalcPopupFormSize();
			ShowPopup();
			gridView.RefreshData();
		}
		private void gridView_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e) {
			if (ReadOnlyCondition != null) {
				DisplayItem o = gridView.GetFocusedRow() as DisplayItem;
				if (o != null) {
					controlAdapter.colSelected.OptionsColumn.ReadOnly = ReadOnlyCondition(o.Value);
				}
			}
		}
		public event System.EventHandler<CollectionChangedEventArgs> ItemChecked;
		private void controlAdapter_SelectionCollectionChanged(object sender, CollectionChangedEventArgs args) {
		    System.EventHandler<CollectionChangedEventArgs> handler = ItemChecked;
			if (handler != null) {
				handler(this, args);
			}
            //this.Text =
            //    (from DisplayItem selectedRow in controlAdapter.GetSelectedRows() select selectedRow).ToArray().JoinString(c => c.DisplayField, ',');
            ////			OnEditValueChanged();
		}
		private void gridView_CustomRowFilter(object sender, DevExpress.XtraGrid.Views.Base.RowFilterEventArgs e) {
			try {
				DisplayItem o = bindingSource[e.ListSourceRow] as DisplayItem;
				if (o != null) {
					if (!string.IsNullOrEmpty(filteComboxEdit.Text)) {
						e.Visible = filteComboxEdit.FiltedItems.Contains(o.Value);
					}
				}
				e.Visible = e.Visible && (ReadOnlyCondition == null || (o != null && !ReadOnlyCondition(o.Value)));
				if (!e.Visible) {
					e.Handled = true;
				}
			}
			catch (Exception ex) {
				MessageBox.Show(ex.ToString());
			}
		}
		private GridControlAdapter controlAdapter;
		private void ComboxItemsChanged(object sender, ComboxItemsChangedArgs e) {
			gridView.RefreshData();
		}
        public void FillCollection<T>(IEnumerable<T> dataArr, Func<T, string> getDisplayText, Func<T, object> getVal)
        {
			controlAdapter.ClearSelection();
			T[] collection = dataArr as T[] ?? dataArr.ToArray();
			filteComboxEdit.FillDisplayItemCollections(collection, getDisplayText, getVal);
			bindingSource.DataSource = collection.Select(c => new DisplayItem(getVal(c), getDisplayText(c)));
			gridView.RefreshData();
			this.ShowPopup();
			this.ClosePopup();
		}
		public void SetSelectItem<T>(Func<T, bool> selected) where T : class {
			if (selected != null) {
				for (int i = 0; i < gridView.RowCount; i++) {
					var row = gridView.GetRow(i) as DisplayItem; 
					controlAdapter.SelectRow(gridView, row, row != null && selected((T)row.Value), false);
				}
			}
			gridView.RefreshData();
		}
		public T[] GetCheckedItem<T>() {
			return (from DisplayItem selectedRow in controlAdapter.GetSelectedRows() select (T) selectedRow.Value).ToArray();
		}
		private Func<object, bool> ReadOnlyCondition;
		public void SetReadOnlyComboBoxItem(Func<object, bool> where) {
			ReadOnlyCondition = where;
			ArrayList ss = controlAdapter.GetSelectedRows();
			gridView.RefreshData();
		}

		//		protected override void DoShowPopup() {
		//			if (flag == 0) {
		//				_filteComboxEdit.EditValue = null;
		//			}
		//			this.FillCollections(DataSource, c => c.DisplayField, c => c.Value, false, null);
		//			if (ShowItems != null) {
		//				_filteComboxEdit.ComboxItemsChanged -= ComboxItemsChanged;
		//				Properties.Items.BeginUpdate();
		//				for (int i = Properties.Items.Count - 1; i > -1; i--) {
		//					CheckedListBoxItem c = Properties.Items[i];
		//					DisplayItem cc = c.Value as DisplayItem;
		//					if (cc != null && !ShowItems.Contains(cc.Value)) {
		//						Properties.Items.RemoveAt(i);
		//					}
		//				}
		//				_filteComboxEdit.ComboxItemsChanged += ComboxItemsChanged;
		//				Properties.Items.EndUpdate();
		//			}
		//			for (int i = 0; i < Properties.Items.Count; i++) {
		//				CheckedListBoxItem c = Properties.Items[i];
		//				DisplayItem cc = c.Value as DisplayItem;
		//				if (cc != null) {
		//					if (EnableCondition != null) {
		//						c.Enabled = EnableCondition(c, cc.Value);
		//					}
		//				}
		//			}
		//			base.DoShowPopup();
		//			if (!this.Properties.PopupControl.Controls.Contains(_filteComboxEdit)) {
		//				this.Properties.PopupControl.Controls.Add(_filteComboxEdit);
		//			}
		//			this.CalcPopupFormSize();
		//			this.PopupForm.Size = new Size(PopupForm.Width, PopupForm.Height + _filteComboxEdit.Height);
		//		}
		//		private IEnumerable<DisplayItem> DataSource;
		//		public void FillCollections<T>(IEnumerable<T> collection, Func<T, string> getDisplayField, Func<T, object> getVal = null) {
		//			DataSource = this.FillCollections(collection, getDisplayField, getVal, false, null);
		//		}
		//		private Func<CheckedListBoxItem, object, bool> EnableCondition;
		//		public void SetEnableCondition(Func<CheckedListBoxItem, object, bool> where) {
		//			EnableCondition = where;
		//		}
		//		private List<object> ShowItems;
		//		private int flag = 0;
		//		private void ComboxItemsChanged(object sender, ComboxItemsChangedArgs comboxItemsChangedArgs) {
		//			try {
		//				if (flag == 1) {
		//					return;
		//				}
		//				if (_filteComboxEdit.EditValue == null) {
		//					ShowItems = null;
		//					return;
		//				}
		//				ShowItems = comboxItemsChangedArgs.Items;
		//				flag = 1;
		//				try {
		//					DoShowPopup();
		//				}
		//				catch (Exception) {
		//				}
		//				flag = 0;
		//				//				this.Properties.PopupControl.Show();
		//				//				this.Properties.PopupControl.Update();
		//				//				this.Properties.PopupControl.Refresh();
		//				//				this.PopupForm.Controls[0].Refresh();
		//			}
		//			catch (Exception ex) {
		//				MessageBox.Error(ex);
		//			}
		//		}
		//		public void FillFilterItem() {
		//			List<DisplayItem> data = (from CheckedListBoxItem c in Properties.Items select c.Value as DisplayItem).ToList();
		//			_filteComboxEdit.FillDisplayItemCollections(data, c => c.DisplayField, c => c.Value);
		//		}
		//		private readonly FilteComboxEdit _filteComboxEdit = new FilteComboxEdit();
		public void ClearSelectItem() {
			EditValue = null;
			controlAdapter.ClearSelection();
		}
	}
}
